#include "gd32f30x.h" 
#include "gd32f30x_i2c.h"
#include "MYIIC.h"
#include "stdio.h"
// 定义I2C超时时间(毫秒)
#define I2C_TIMEOUT_MS 10

// // I2C状态枚举
// typedef enum {
//     I2C_STATUS_OK,
//     I2C_STATUS_BUSY,
//     I2C_STATUS_TIMEOUT,
//     I2C_STATUS_NACK,
//     I2C_STATUS_ERROR
// } I2C_StatusTypeDef;

/**
 * @brief  I2C主机发送数据函数
 * @param  i2c_periph: I2C外设基地址 (I2C0或I2C1)
 * @param  dev_addr: 从设备地址(7位)
 * @param  p_data: 指向要发送的数据缓冲区
 * @param  size: 要发送的数据长度
 * @retval I2C状态
 */
I2C_StatusTypeDef i2c_master_transmit(uint32_t i2c_periph, uint8_t dev_addr, 
                                     uint8_t *p_data, uint16_t size) {
    uint32_t timeout;
    
    // 检查参数有效性
    if((NULL == p_data) || (0 == size)) {
        return I2C_STATUS_ERROR;
    }
    
    // 检查I2C总线是否空闲
    timeout = I2C_TIMEOUT_MS * 1000; // 转换为微秒
    while(i2c_flag_get(i2c_periph, I2C_FLAG_I2CBSY)) {
        if(0 == timeout--) {
            return I2C_STATUS_TIMEOUT;
        }
    }
    
    // 发送起始信号
    i2c_start_on_bus(i2c_periph);
    
    // 等待起始信号发送完成
    timeout = I2C_TIMEOUT_MS * 1000;
    while(!i2c_flag_get(i2c_periph, I2C_FLAG_SBSEND)) {
        if(0 == timeout--) {
            // 发送停止信号以恢复总线
            i2c_stop_on_bus(i2c_periph);
            return I2C_STATUS_TIMEOUT;
        }
    }
    
    // 发送从设备地址(写操作)
    i2c_master_addressing(i2c_periph, dev_addr, I2C_TRANSMITTER);
    
    // 等待地址发送完成并检查应答
    timeout = I2C_TIMEOUT_MS * 1000;
    while(!i2c_flag_get(i2c_periph, I2C_FLAG_ADDSEND)) {
        if(0 == timeout--) {
            // 发送停止信号以恢复总线
            i2c_stop_on_bus(i2c_periph);
            return I2C_STATUS_TIMEOUT;
        }
        
        // 检查是否收到非应答
        if(i2c_flag_get(i2c_periph, I2C_FLAG_AERR)) {
            i2c_flag_clear(i2c_periph, I2C_FLAG_AERR);
            i2c_stop_on_bus(i2c_periph);
            return I2C_STATUS_NACK;
        }
    }
    
    // 清除地址发送完成标志
    i2c_flag_clear(i2c_periph, I2C_FLAG_ADDSEND);
    
    // 发送数据
    while(size--) {
        // 等待发送缓冲区为空
        timeout = I2C_TIMEOUT_MS * 1000;
        while(!i2c_flag_get(i2c_periph, I2C_FLAG_TBE)) {
            if(0 == timeout--) {
                i2c_stop_on_bus(i2c_periph);
                return I2C_STATUS_TIMEOUT;
            }
        }
        
        // 发送一个字节数据
        i2c_data_transmit(i2c_periph, *p_data++);
        
        // 等待数据发送完成
        timeout = I2C_TIMEOUT_MS * 1000;
        while(!i2c_flag_get(i2c_periph, I2C_FLAG_BTC)) {
            if(0 == timeout--) {
                i2c_stop_on_bus(i2c_periph);
                return I2C_STATUS_TIMEOUT;
            }
            
            // 检查是否收到非应答
            if(i2c_flag_get(i2c_periph, I2C_FLAG_AERR)) {
                i2c_flag_clear(i2c_periph, I2C_FLAG_AERR);
                i2c_stop_on_bus(i2c_periph);
                return I2C_STATUS_NACK;
            }
        }
    }
    
    // 等待最后一个字节发送完成
    timeout = I2C_TIMEOUT_MS * 1000;
    while(!i2c_flag_get(i2c_periph, I2C_FLAG_TBE)) {
        if(0 == timeout--) {
            i2c_stop_on_bus(i2c_periph);
            return I2C_STATUS_TIMEOUT;
        }
    }
    
    // 发送停止信号
    i2c_stop_on_bus(i2c_periph);
    
    // 等待停止信号发送完成
    timeout = I2C_TIMEOUT_MS * 1000;
    while(i2c_flag_get(i2c_periph, I2C_FLAG_I2CBSY)) {
        if(0 == timeout--) {
            return I2C_STATUS_TIMEOUT;
        }
    }
    
    return I2C_STATUS_OK;
}
void MYIIC_Init(uint32_t addre)
{
	rcu_periph_clock_enable(RCU_I2C0);
	rcu_periph_clock_enable(RCU_GPIOB);

	gpio_init(GPIOB, GPIO_MODE_AF_OD, GPIO_OSPEED_50MHZ, GPIO_PIN_6);
	gpio_init(GPIOB, GPIO_MODE_AF_OD, GPIO_OSPEED_50MHZ, GPIO_PIN_7);

	i2c_clock_config(I2C0, 400000, I2C_DTCY_2);
	i2c_mode_addr_config(I2C0, I2C_I2CMODE_ENABLE, I2C_ADDFORMAT_7BITS, addre);
	i2c_enable(I2C0);
	i2c_ack_config(I2C0, I2C_ACK_ENABLE);
}